using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gko.Utils
{
	public class Scope : DisposableBase
	{
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
		public static readonly Scope Empty = new Scope(null);
		private Action action;

		private Scope(Action action)
		{
			this.action = action;
		}

		public static Scope Create(Action action)
		{
			return new Scope(action);
		}

		public static Scope Create<TDisposable>(TDisposable disposable) where TDisposable : IDisposable
		{
			return ReferenceEquals(disposable, null) ? Empty : new Scope(disposable.Dispose);
		}

		public void Cancel()
		{
			this.action = null;			
		}

		public Scope Transfer()
		{
			using (Create(() => this.action = null)) {
				return new Scope(this.action);
			}
		}

		protected override void OnDispose()
		{
			base.OnDispose();
			if(this.action != null) {
				this.action();
				this.action = null;
			}
		}
	}
}